# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# File       : curve_data_view.py
# Time       ：2023/11/1 21:55
# Author     ：Y-aong
# version    ：python 3.10
# Description：运行状态柱状图
"""
from datetime import datetime, timedelta

from flask_restx import fields
from sqlalchemy import func, case

from apis.home import home_ns
from apis.home.schema.run_status_schema import RunStatusBarSchema
from apis.orderlines.models import ProcessInstance
from orderlines.utils.orderlines_enum import ProcessStates
from public.api_utils.api_decorator import handle_api_error
from public.base_model import db
from public.base_response import generate_response, MarshalModel
from public.base_view import AbstractView

curve_data = home_ns.model('curve_data', {'spotName': fields.String(), 'value': fields.String()})
curve_data_marshal = MarshalModel('curve_data', home_ns)


class CurveDataView(AbstractView):
    url = '/curve_data'

    def __init__(self, *args, **kwargs):
        super(CurveDataView, self).__init__(*args, **kwargs)
        self.filter = list()
        self.current_data = f"{datetime.now().strftime('%Y-%m-%d')} 23.59.59"
        self.last_data = f"{(datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')} 23.59.59"
        self.last_week = f"{(datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d')} 23.59.59"
        self.last_month = f"{(datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')} 23.59.59"
        self.keys = ['运行成功', '运行失败', '运行超时', '运行停止', '运行暂停', '运行继续', '运行排队', '运行中']

    def get_run_status(self):

        # 更改 case() 调用以使用位置参数
        spot_case = case(
            (ProcessInstance.process_status == ProcessStates.green.value, '运行成功'),
            (ProcessInstance.process_status == ProcessStates.red.value, '运行失败'),
            (ProcessInstance.process_status == ProcessStates.yellow.value, '运行停止'),
            (ProcessInstance.process_status == ProcessStates.grey.value, '运行排队'),
            (ProcessInstance.process_status == ProcessStates.blue.value, '运行中'),
            (ProcessInstance.process_status == ProcessStates.purple.value, '运行暂停'),
            (ProcessInstance.process_status == ProcessStates.orange.value, '运行超时'),
            else_='未知状态'
        ).label('spotName')

        # 使用 group_by 和 case 表达式来为每个状态计算计数
        objs = db.session.query(
            spot_case,
            func.count(ProcessInstance.id).label('value')
        ).filter(*self.filter).group_by(spot_case).all()

        info = RunStatusBarSchema().dump(objs, many=True)
        info = [item for item in info if item.get('spotName')]
        exist_keys = [item.get('spotName') for item in info]
        not_exist_keys = [item for item in self.keys if item not in exist_keys]

        # 添加缺失的状态
        for key in not_exist_keys:
            info.append({'spotName': key, 'value': 0})

        info.sort(key=lambda item: item.get('spotName'))
        return info

    @handle_api_error()
    @home_ns.doc(description='运行状态柱状图')
    @home_ns.marshal_with(curve_data_marshal.list_response(curve_data, is_db=False))
    def get(self):
        """运行状态柱状图"""
        self.filter.append(ProcessInstance.active == 1)
        date_type = self.form_data.get('date')
        if date_type == 'day':
            self.filter.append(ProcessInstance.start_time.between(self.last_data, self.current_data))
        elif date_type == 'week':
            self.filter.append(ProcessInstance.start_time.between(self.last_week, self.current_data))
        else:
            self.filter.append(ProcessInstance.start_time.between(self.last_month, self.current_data))

        response_data = self.get_run_status()
        return generate_response(response_data)
